#include "cv.h"
#include "highgui.h"
#include <iostream>

using namespace cv;
using namespace std;

int main(int, char**)
{
    VideoCapture cap("/Users/mayakreidieh/Documents/FYP/Videos/right_temp.mov"); // open the movie
    if(!cap.isOpened())  // check if we succeeded
        return -1;
	int count=0;
	double summ;
	Mat img, background, background_gs;
	Mat frame_gs,backgroun_gs_prev,diff, bw,new_back, temp3, bw1;
	Scalar s(255);

	//Read First Frame
	cap>>background;
	//Convert to grayscale
	cvtColor( background, background_gs, CV_RGB2GRAY );
	
	//Declare windows

	//Holds updated background in grayscale
	namedWindow("background_gs", 1);
	imshow("background_gs", background_gs);
	//Holds hand
	namedWindow("Hand_gs", 1);
	//Holds grayscale version of the input
    namedWindow("Grayscale",1);
	//Holds binary of difference between background and current frame
	namedWindow("Binary",1);
	//Holds grayscale video with hand filtered out (blacked out)
	namedWindow("Difference",1);
	//Holds frame to frame differencing
	namedWindow("Difference2",1);
	//Holds new background
	namedWindow("New Background",1);
	namedWindow("test1",1);
	namedWindow("test2",1);

	//initialize previous frame to first frame (not necessary)
	background_gs.copyTo(backgroun_gs_prev);

	bool detected_touch = false;
	bool updating_background = false;

	int frame_num = 1;
    for(;;)
    {
	    
	    // Read frame number
	    frame_num++;
	    
	    // Assume touch is detected at frame 30*13
	    if (frame_num == 30*14)
	    	detected_touch = true;
	    	
        Mat frame;
		// get a new frame from movie
        cap >> frame;
        
		//convert to grayscale
        cvtColor(frame, frame_gs, CV_BGR2GRAY);
		
		//compute difference
		diff=frame_gs-background_gs;
        imshow("Grayscale", frame_gs);
	
		//Thresholding of difference to get binary image
		bw = diff > 64;
		//Code to erode and dilate, not necessary so far
		//erode(bw,bw, Mat(), Point (-1,-1), 1);
		//dilate(bw, bw, Mat(), Point(-1,-1), 1);
		imshow("Binary", bw);	


		//Touch is detected 
		if(detected_touch){ //if not first frame
			//invert binary
			Mat temp2 = (s-bw);
			divide(temp2,s,temp2);
			//filter out the hand
			multiply(temp2,frame_gs,new_back, 1.0);
			imshow("Difference", new_back);
			updating_background = true;
			detected_touch = false;
			cout << "\n Touch detected. \n";
			bw.copyTo(bw1);
		}
		
				
		if(updating_background){ 
			Mat diff2;
			cout << "\n Uptdating Background : ";
			//get frame to frame difference
			absdiff(frame_gs,backgroun_gs_prev,diff2);
			imshow("Difference2", diff2);

			//update previous frame
			frame_gs.copyTo(backgroun_gs_prev);
			

			//threshold to be changed
				Mat temp1,temp3;
				//get hand only (change only)
				//imshow("test1", bw);
				divide(bw1,s,temp1);
//				imshow("test2", temp1);
				multiply(frame_gs,temp1,temp3);
				Scalar temp=sum(temp3);
				summ=temp.val[0];
				cout<<summ;
				cout<<"\n";
				


				imshow("Hand_gs", temp3);
			if(summ<400000){ 
				//add back to background
				background_gs=new_back+temp3;
				imshow("New Background", background_gs);
				summ=0;
				updating_background = false;
				
			}
			}

		count++;
        if(waitKey(30) >= 0) break;
    }
    // the camera will be deinitialized automatically in VideoCapture destructor
    return 0;
}